﻿namespace Microsoft.SharePoint.Client
{
    using System;
    using System.Globalization;
    using System.Xml;

    internal class ExecutionScope : IDisposable
    {
        private Microsoft.SharePoint.Client.ClientActionExecutionScopeStart m_clientActionExecutionScopeStart;
        private ClientRuntimeContext m_context;
        private bool m_disposed;
        private ExecutionScopeDisposingCallback m_disposingCallback;
        private long m_id;
        private string m_name;

        internal ExecutionScope(ClientRuntimeContext context, string name, ExecutionScopeDisposingCallback disposingCallback)
        {
            this.m_context = context;
            this.m_name = name;
            this.m_id = ClientRequest.NextSequenceId;
            this.m_context.PendingRequest.ExecutionScopes.Push(this);
            this.m_clientActionExecutionScopeStart = new Microsoft.SharePoint.Client.ClientActionExecutionScopeStart(this, this.m_name);
            this.m_context.PendingRequest.AddQuery(this.m_clientActionExecutionScopeStart);
            this.m_disposingCallback = disposingCallback;
        }

        public void Dispose()
        {
            if (this.m_disposed)
            {
                throw ExceptionHandlingScope.CreateInvalidUsageException();
            }
            if (this.m_disposingCallback != null)
            {
                this.m_disposingCallback();
            }
            if ((this.m_context.PendingRequest.ExecutionScopes.Count <= 0) || (this.m_context.PendingRequest.ExecutionScopes.Pop() != this))
            {
                throw ExceptionHandlingScope.CreateInvalidUsageException();
            }
            this.m_context.PendingRequest.AddQuery(new ClientActionExecutionScopeEnd(this, this.m_name));
            this.m_disposed = true;
        }

        internal virtual void WriteEnd(XmlWriter writer, SerializationContext serializationContext)
        {
            writer.WriteEndElement();
        }

        internal virtual void WriteStart(XmlWriter writer, SerializationContext serializationContext)
        {
            writer.WriteStartElement(this.m_name);
            writer.WriteAttributeString("Id", this.Id.ToString(CultureInfo.InvariantCulture));
        }

        internal Microsoft.SharePoint.Client.ClientActionExecutionScopeStart ClientActionExecutionScopeStart
        {
            get
            {
                return this.m_clientActionExecutionScopeStart;
            }
        }

        internal bool Disposed
        {
            get
            {
                return this.m_disposed;
            }
        }

        public long Id
        {
            get
            {
                return this.m_id;
            }
        }

        public string Name
        {
            get
            {
                return this.m_name;
            }
        }
    }
}

